package dvoz.main;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;

import javax.swing.*;

import dvoz.assembler.Assembler;
import dvoz.components.*;

@SuppressWarnings("serial")
public class AssemblerFrame extends JFrame {

	private HashMap<String, LogicalComponent> components;
	private JTextArea text = new JTextArea();
	private JPanel east = new JPanel();
	private JButton load, assemble, resetmem;
	private JLabel status;

	public AssemblerFrame(HashMap<String, LogicalComponent> components) {
		super("Asembler");
		this.components = components;
		setLocation(150, 150);
		setLayout(new BorderLayout());
		JScrollPane scroll = new JScrollPane(text);
		scroll.setBorder(BorderFactory.createTitledBorder("Program"));
		add("Center", scroll);

		east.setLayout(new BorderLayout());
		east.setPreferredSize(new Dimension(180, 300));
		JPanel eastUp = new JPanel(new GridLayout(3, 1,5,5));
		eastUp.setBorder(BorderFactory.createTitledBorder("Komande"));
		load = new JButton("Ucitavanje programa");
		load.setAlignmentX(CENTER_ALIGNMENT);
		eastUp.add(load);
		assemble = new JButton("Prevodjenje programa");
		assemble.setAlignmentX(CENTER_ALIGNMENT);
		eastUp.add(assemble);
		resetmem = new JButton("Resetovanje memorije");
		resetmem.setAlignmentX(CENTER_ALIGNMENT);
		eastUp.add(resetmem);
		east.add("North", eastUp);
		JPanel eastCenter = new JPanel(new GridLayout(1,1,5,5));
		eastCenter.setBorder(BorderFactory.createTitledBorder("Status"));
		status = new JLabel("");
		status.setAlignmentX(CENTER_ALIGNMENT);
		status.setAlignmentY(TOP_ALIGNMENT);
		eastCenter.add(status);
		east.add("Center",eastCenter);
		
		add("East", east);

		setSize(400, 300);
		setMinimumSize(new Dimension(400, 300));
		setPreferredSize(new Dimension(400, 300));
		validate();
		setVisible(false);

		load.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent arg0) {
				executeLOAD();
			}
		});
		
		assemble.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent arg0) {
				executeASSEMBLE();
			}
		});
		
		resetmem.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent arg0) {
				executeRESETMEM();
			}
		});

	}

	private void executeLOAD() {
		JFileChooser chooser = new JFileChooser("tests");
		int returnVal = chooser.showOpenDialog(AssemblerFrame.this);
		if (returnVal == JFileChooser.APPROVE_OPTION) {
			setTitle(chooser.getSelectedFile().getName());
			String asmcode = chooser.getSelectedFile().getAbsolutePath();
			BufferedReader read;
			StringBuffer asmBuffer = new StringBuffer();
			try {
				read = new BufferedReader(new FileReader(asmcode));
				String nextLine;
				String oneLine = read.readLine();
				while (oneLine != null) {
					
					nextLine = read.readLine();
					if (oneLine != null && oneLine!="\n" && oneLine!=" "){
						if(nextLine==null)asmBuffer.append(oneLine);
						else asmBuffer.append(oneLine + "\n");
					}
					oneLine=nextLine;
				}
				read.close();

				text.setText(asmBuffer.toString());
				status.setText("<html>Program je uspesno ucitan iz fajla.</html>");
				
			} catch (FileNotFoundException e) {
				status.setText("<html>Greska pri otvaranju fajla.</html>");
			} catch (IOException e) {
				status.setText("<html>Greska pri otvaranju fajla.</html>");
			}
		}
	}
	private void executeASSEMBLE(){
		Assembler asem=new Assembler(text.getText(), false, null);
		if(asem.getCode() != null){
			((MEM) components.get("mem_oper.mem")).setMemory(asem.getCode());
			((REG) components.get("fetch1.pc")).setVal(asem.getStartOfCode());
			status.setText("<html>Program je uspesno preveden i smesten u memoriju.</html>");
			text.setText("");
		}else{
			status.setText("<html>"+asem.getErrorMessage()+"</html>");
		}
	}
	private void executeRESETMEM(){
		((MEM) components.get("mem_oper.mem")).clear();
		status.setText("<html>Sadrzaj memorije je uspesno resetovan.</html>");
	}

	public void resetLabels() {// when opet this frame
		text.setText("");
		status.setText("");
	}

}
